#pragma once
#include <iostream>
#include <pthread.h>
#include <functional>

using std::cin;
using std::cout;
using std::endl;
using std::string;

template <typename T>
using func_t = std::function<void(T &)>;

template <typename T>
class Thread
{
private:
    pthread_t _tid;
    string _thread_name;
    bool _isrunning;
    func_t<T> _func;
    T _data;

public:
    Thread<T>(func_t<T> __func, string &__thread_name, T &__data)
        : _func(__func), _thread_name(__thread_name), _isrunning(false), _tid(0), _data(__data)
    {
    }
    ~Thread()   //不加模板？？？
    {
    }

    string ThreadName()
    {
        return _thread_name;
    }

    static void *ThreadRoutine(void *args)
    {
        // pthread_create 函数第三个参数传入的函数指针必须是 void*(void*)的
        // 但是成员函数自带this指针,相当于有第三个参数，所以需要修饰为static函数

        Thread *ts = static_cast<Thread *>(args);

        //(void*)args;  //防止编译器告警
        ts->_func(ts->_data);
        return nullptr;
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if (n == 0)
        {
            _isrunning = true;
            return true;
        }
        return false;
    }

    bool IsRunning()
    {
        return _isrunning;
    }

    bool Join()
    {
        if (!_isrunning)
            return true;
        int n = pthread_join(_tid, nullptr);
        if (n == 0) // 等待成功
        {
            _isrunning = false;
            return true;
        }
        return false;
    }
};